/**
 * Copyright(c) 2013 Jade Techonologies Co., Ltd.
 *
 * History:
 *   13-4-18 上午11:05 Created by sky
 */
package com.jade.bss.admin.account.impl;

import java.util.List;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.jade.bss.admin.AdminException;
import com.jade.bss.admin.account.AdminAccount;
import com.jade.bss.admin.account.AdminAccountDao;
import com.jade.framework.base.criterion.Criteria;
import com.jade.framework.base.criterion.sql.SqlUtils;
import com.jade.framework.base.util.PagingList;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;

/**
 * 采用JPA方式实现的管理员数据访问接口。
 *
 * @author sky
 * @version 1.0 13-4-18 上午11:05
 */
@Named ("bss_adminAccountDao")
public class JpaAccountDao
        implements AdminAccountDao
{
    @PersistenceContext (unitName = "default")
    protected EntityManager entityManager;

    @Caching (evict = {@CacheEvict (value = "bss.admin.g", key = "#admin.id"),
            @CacheEvict (value = "bss.admin.l", allEntries = true),
            @CacheEvict (value = "bss.admin.q", allEntries = true)})
    public int addAdmin(AdminAccount admin)
            throws AdminException
    {
        entityManager.persist(admin);
        return admin.getId();
    }

    @Caching (evict = {@CacheEvict (value = "bss.admin.g", key = "#admin.id"),
            @CacheEvict (value = "bss.admin.l", allEntries = true),
            @CacheEvict (value = "bss.admin.q", allEntries = true)})
    public void updateAdmin(AdminAccount admin)
            throws AdminException
    {
        entityManager.merge(admin);
    }

    @Caching (evict = {@CacheEvict (value = "bss.admin.g", key = "#admin.id"),
            @CacheEvict (value = "bss.admin.l", allEntries = true),
            @CacheEvict (value = "bss.admin.q", allEntries = true)})
    public void removeAdmin(AdminAccount admin)
            throws AdminException
    {
        /** 传入的参数agent可能不是 attached的对象，不能直接调用 entityManager.remove()。
         * 可以通过先find再remove的方式删除，在没有需要级联删除的时候可以通过JPQL来删除。
         * 传入admin对象作为参数，主要是为了进行cache相关的操作，以提升性能。
         */
        String sql = "DELETE FROM AdminAccount WHERE id=:id";
        Query query = entityManager.createQuery(sql);
        query.setParameter("id", admin.getId());
        query.executeUpdate();
    }

    @Cacheable (value = "bss.admin.g", key = "#id")
    public AdminAccount getAdmin(int id)
    {
        return entityManager.find(AdminAccount.class, id);
    }

    @Cacheable (value = "bss.admin.q", key = "#criteria.toString()")
    public PagingList<AdminAccount> queryAdmin(Criteria criteria)
    {
        String hsql = "SELECT admin FROM AdminAccount admin";
        return SqlUtils.sqlQuery(hsql, entityManager, criteria);
    }

    @Cacheable (value = "bss.admin.l", key = "#criteria.toString()")
    public List<AdminAccount> listAdmin(Criteria criteria)
    {
        String hsql = "SELECT admin FROM AdminAccount admin";
        return SqlUtils.sqlQueryWithoutCount(hsql, entityManager, criteria);
    }
}
